package com.mybed.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mybed.crm.common.enums.HttpCodeEnum;
import com.mybed.crm.exception.BaseException;
import com.mybed.crm.mapper.MenuByRouterMapper;
import com.mybed.crm.mapper.MenuMapper;
import com.mybed.crm.pojo.pojo.Dept;
import com.mybed.crm.pojo.pojo.Menu;
import com.mybed.crm.pojo.pojo.MenuByRouter;
import com.mybed.crm.pojo.pojo.Role;
import com.mybed.crm.pojo.vo.*;
import com.mybed.crm.result.MenuResult;
import com.mybed.crm.result.Result;
import com.mybed.crm.service.MenuService;
import com.mybed.crm.service.RoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    @Autowired
    private MenuByRouterMapper menuByRouterMapper;
    @Autowired
    private RoleService roleService;
    @Override
    public Result getRouters() {
        List<MenuByRouter> menuByRouters = menuByRouterMapper.selectList(null);
        Map<Integer, MenuByRouterAndChildrenVo> menu = new HashMap<>();
        /*menuByRouters.stream().map(o -> {
            MenuByRouterAndChildrenVo menuByRouterAndChildrenVo = new MenuByRouterAndChildrenVo();
            BeanUtils.copyProperties(menuByRouters, menuByRouterAndChildrenVo);
            return menuByRouterAndChildrenVo;
        }).collect(Collectors.toMap(MenuByRouterAndChildrenVo::getMenuId, Function.identity()));*/
        for (MenuByRouter menuByRouter : menuByRouters) {
            MenuByRouterAndChildrenVo menuByRouterAndChildrenVo = new MenuByRouterAndChildrenVo();
            BeanUtils.copyProperties(menuByRouter, menuByRouterAndChildrenVo);
            menu.put(menuByRouterAndChildrenVo.getMenuId(),menuByRouterAndChildrenVo);
        }
        Map<String, MenuByRouter> menuByName = menuByRouters.stream().collect(Collectors.toMap(MenuByRouter::getMenuName, Function.identity()));
        Map<String, RtouerAndChildren> routerMap=new HashMap<>(); /*= menuByRouters.stream().map(o -> {
            Meta meta = new Meta();
            RtouerAndChildren router = new RtouerAndChildren();
            BeanUtils.copyProperties(o, meta);
            meta.setTitle(o.getMenuName());
            meta.setNoCache(o.getIsCache());
            BeanUtils.copyProperties(o, router);
            router.setHidden(o.getVisible());
            router.setMeta(meta);
            return router;
        }).collect(Collectors.toMap(r -> r.getMeta().getTitle(), Function.identity()));*/
        for (MenuByRouter o : menuByRouters) {
            Meta meta = new Meta();
            RtouerAndChildren router = new RtouerAndChildren();
            BeanUtils.copyProperties(o, meta);
            meta.setTitle(o.getMenuName());
            meta.setNoCache(o.getIsCache());
            BeanUtils.copyProperties(o, router);
            router.setHidden(o.getVisible());
            router.setMeta(meta);
            routerMap.put(router.getMeta().getTitle(),router);
        }
        Map<Integer, RtouerAndChildren> routerMapById=new HashMap<>();
        for (MenuByRouter o : menuByRouters) {
            Meta meta = new Meta();
            RtouerAndChildren router = new RtouerAndChildren();
            BeanUtils.copyProperties(o, meta);
            meta.setTitle(o.getMenuName());
            meta.setNoCache(o.getIsCache());
            BeanUtils.copyProperties(o, router);
            router.setHidden(o.getVisible());
            router.setMeta(meta);
            routerMapById.put(o.getMenuId(),router);
        }
        List<MenuByRouterAndChildrenVo> result=new ArrayList<>();
        for (MenuByRouter menuByRouter : menuByRouters) {
            if(menuByRouter.getParentId()!=0){
                menu.get(menuByRouter.getParentId()).getChildren().add(menu.get(menuByRouter.getMenuId()));
            }else {
                result.add(menu.get(menuByRouter.getMenuId()));
            }
        }
        List<Router> endResult=new ArrayList<>();
        for (MenuByRouterAndChildrenVo menuByRouterAndChildrenVo : result) {
            f(menuByRouterAndChildrenVo,routerMap,endResult);
        }
        /*routerMap.forEach((o,e)->{
            String title = e.getMeta().getTitle();
            MenuByRouter menu1 = menuByName.get(title);
            String menuName = menu1.getParentName();
            if(!StringUtils.hasLength(menuName)){
                endResult.add(e);
            }
        });*/

        /*routerMap.forEach((o,e)->{
            //找到孩子为空的router
            if(CollectionUtils.isEmpty(e.getChildren())){
                //找到孩子的父,先从最终结果中找,如果没找到直接转换为RouterChildren,找到就先移除再添加RouterChildren
                if(endResult.contains(e)){
                    RouterChildren routerChildren=new RouterChildren();
                    BeanUtils.copyProperties(e,routerChildren);
                    endResult.remove(e);
                    endResult.add(routerChildren);
                }{
                    routerMap.forEach((u,i)->{
                        List<Router> iChildren = i.getChildren();
                        if(iChildren.contains(e)){
                            iChildren.remove(i);
                            RouterChildren routerChildren=new RouterChildren();
                            BeanUtils.copyProperties(e,routerChildren);
                            iChildren.remove(e);
                            iChildren.add(routerChildren);
                        }
                    });
                }
            }
        });*/

        return Result.success(endResult);
        /*menu.forEach((o,e)->{
            if(CollectionUtils.isEmpty(e.getChildren())){
                Integer parentId = deptMap.get(e.getId()).getParentId();
                Children children=new Children();
                BeanUtils.copyProperties(e,children);
                DAC.get(parentId).getChildren().remove(e);
                DAC.get(parentId).getChildren().add(children);
            }
        });*/
    }

    @Override
    public Result treeselect() {
        List<Menu> list=list();
        Map<Integer, Menu> Menumap = list.stream().collect(Collectors.toMap(Menu::getMenuId, Function.identity()));
        Map<Integer,DeptAndChildren> DAC=list.stream().map(o -> {
            DeptAndChildren dac = new DeptAndChildren();
            dac.setId(o.getMenuId());
            dac.setLabel(o.getMenuName());
            return dac;
        }).collect(Collectors.toMap(DeptAndChildren::getId, Function.identity()));
        List<Children> result=new ArrayList<>();
        for (Menu dept : list) {
            if(dept.getParentId()!=0){
                DAC.get(dept.getParentId()).getChildren().add(DAC.get(dept.getMenuId()));
            }else {
                result.add(DAC.get(dept.getMenuId()));
            }
        }
        DAC.forEach((o,e)->{
            if(CollectionUtils.isEmpty(e.getChildren())){
                Integer parentId = Menumap.get(e.getId()).getParentId();
                Children children=new Children();
                BeanUtils.copyProperties(e,children);
                if(parentId!=0){
                    try {
                        DAC.get(parentId).getChildren().remove(e);
                        DAC.get(parentId).getChildren().add(children);
                    } catch (Exception ex) {
                        throw new BaseException("菜单为null:+"+parentId);
                    }
                }

            }
        });
        return Result.success(result);
    }

    @Override
    public MenuResult roleMenuTreeselect(Integer id) {
        LambdaQueryWrapper<Role> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRoleId,id);
        Role one = roleService.getOne(wrapper);
        List<Children> treeselect = roletreeselect();
        MenuResult result=new MenuResult();
        List<Integer> list=new ArrayList<>();
        if(StringUtils.hasLength(one.getMenuIds())){
            list= Arrays.stream(one.getMenuIds().split(",")).map(Integer::parseInt).collect(Collectors.toList());
        }

        result.setMenus(treeselect);
        result.setCheckedKeys(list);
        result.setCode(HttpCodeEnum.SUCCESS.getCode());
        result.setMsg(HttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }
    public List<Children> roletreeselect() {
        List<Menu> list=list();
        Map<Integer, Menu> Menumap = list.stream().collect(Collectors.toMap(Menu::getMenuId, Function.identity()));
        Map<Integer, DeptAndChildren> DAC=list.stream().map(o -> {
            DeptAndChildren dac = new DeptAndChildren();
            dac.setId(o.getMenuId());
            dac.setLabel(o.getMenuName());
            return dac;
        }).collect(Collectors.toMap(DeptAndChildren::getId, Function.identity()));
        List<Children> result=new ArrayList<>();
        for (Menu dept : list) {
            if(dept.getParentId()!=0){
                DAC.get(dept.getParentId()).getChildren().add(DAC.get(dept.getMenuId()));
            }else {
                result.add(DAC.get(dept.getMenuId()));
            }
        }
        DAC.forEach((o,e)->{
            if(CollectionUtils.isEmpty(e.getChildren())){
                Integer parentId = Menumap.get(e.getId()).getParentId();
                Children children=new Children();
                BeanUtils.copyProperties(e,children);
                if(parentId!=0){
                    try {
                        DAC.get(parentId).getChildren().remove(e);
                        DAC.get(parentId).getChildren().add(children);
                    } catch (Exception ex) {
                        throw new BaseException("菜单为null:+"+parentId);
                    }
                }

            }
        });
        return result;
    }


    public void f(MenuByRouterAndChildrenVo result,Map<String, RtouerAndChildren> routerMap,List<Router> endResult){
        if(!CollectionUtils.isEmpty(result.getChildren())){
            for (MenuByRouterAndChildrenVo child : result.getChildren()) {
                f(child,routerMap,endResult);
            }
        }
        if(!StringUtils.hasLength(result.getParentName())){
            endResult.add(routerMap.get(result.getMenuName()));
            return;
        }
        RtouerAndChildren rtouerAndChildren = routerMap.get(result.getParentName());
        List<Router> children = rtouerAndChildren.getChildren();
        children.add(routerMap.get(result.getMenuName()));
    }
}
